package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
@Service
@Transactional
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;


    @Override
    public void insertAudit(Application application) {
        log.debug("根据申请生成审批数据业务:application={}", application);
        //1.获取审批人id集合
        List<Long> userIdList = application.getAuditUserIdList();
        //2.遍历审批人集合,有几个人,生成几条审批数据
        for (int i = 0; i < userIdList.size(); i++){
            Audit audit = new Audit();
            audit.setApplicationId(application.getId());
            audit.setAuditUserId(userIdList.get(i));
            audit.setAuditSort(i);
            if(i==0){
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }else {
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            audit.setCreateTime(new Date());
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectByApplicationId(Long id) {
        log.debug("根据申请单id查询审批数据业务:id={}", id);
        List<AuditVO> List = auditMapper.selectByApplicationId(id);
        return List;
    }

    @Override
    public List<AuditVO> selectAll(AuditQuery auditQuery) {
        log.debug("查询审批数据业务:auditQuery={}", auditQuery);
        List<AuditVO> list = auditMapper.selectAll(auditQuery);
        for (int i = 0; i < list.size(); i++) {
            AuditVO auditVO = list.get(i);
            // 处理申请单VO,给当前的申请单VO对象补充审批人信息
            log.debug("准备处理申请单VO,给当前的申请单VO对象补充审批人信息:auditVO={}", auditVO);
            assignAuditUserList(auditVO);
        }
        return list;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批数据业务:auditSaveParam={}", auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam, audit);
        audit.setUpdateTime(new Date());
        // 准备当前审批单对应的申请单对象
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        // 我们需要判断是否是 通过 或  驳回,根据状态码判断
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){
            // 通过=对应操作
            auditMapper.update(audit);
            /* 继续查当前审批单对应的申请单下是否有其他审批单 */
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //BeanUtils.copyProperties(audit, auditQuery);
            // 根据申请单id查询该申请单下是否有其他审批单的总数(注意当前审批单已经通过,状态已经改变)
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            //log.debug("根据申请单id查询该申请单下是否有其他审批单的总数:auditQuery={}", auditQuery);
            //log.debug("根据申请单id查询该申请单下是否有其他审批单的总数:count={}", count);
            if (count>0){// 还有没批的审批单
                //下一条审批数据是当前审批数据的次序+1
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                List<AuditVO> auditVOList = auditMapper.selectAll(auditQuery);
                if(auditVOList != null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    // 创建第二个空的审批单对象
                    Audit audit2 = new Audit();
                    BeanUtils.copyProperties(auditVO, audit2);
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    auditMapper.update(audit2);
                }
                // 设置申请单的状态为"审核中"
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.cancelStatus(application);
            }else { // 没有未审批的审批单了
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.cancelStatus(application);
            }
        }else if(audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())){
            // 驳回=对应操作,设置审批单的状态为"40"
            auditMapper.update(audit);
            /* 继续查当前审批单对应的申请单下是否有其他审批单 */
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            // 根据申请单id查询该申请单下的所有审批单
            List<AuditVO> auditVOList = auditMapper.selectAll(auditQuery);
            if(auditVOList != null && auditVOList.size() > 0 ){
                for (int i = 0; i < auditVOList.size(); i++) {
                    AuditVO auditVO = auditVOList.get(i);
                    if (AuditStatusEnum.PENDING.getCode().equals(auditVO.getAuditStatus())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            // 设置申请单的状态为"驳回",并设置驳回原因
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.cancelStatus(application);
        }
    }

    private void assignAuditUserList(AuditVO auditVO) {
        // 准备空集合,分别用来保存审批人id和审批人姓名
        List<String> auditUsernameList = new ArrayList<>();
        List<Long> auditUserIdList = new ArrayList<>();
        // 根据审批单VO中的申请单id,查询当前审批单对应的申请单下的所有审批单数据
        List<AuditVO> auditList = auditMapper.selectByApplicationId(auditVO.getApplicationId());
        // 遍历每一个审批单,获取每个审批单中的审批人id和姓名
        for (int i = 0; i < auditList.size(); i++) {
            AuditVO audit = auditList.get(i);
            // 取出当前审批单中的审批人id,并存入上方的空集合中
            Long id = audit.getAuditUserId();
            auditUserIdList.add(id);
            // 5.根据刚刚取出的审批人id,查出对应的审批人姓名,并存入上方的空集合中
            UserVO user = userMapper.selectByParentId(id);
            auditUsernameList.add(user.getUsername());
        }
        // 6.准备一个拼接工具,帮我们将所有审批人姓名连接成一个字符串
        StringJoiner sj = new StringJoiner(",");
        for (String username : auditUsernameList) {
            sj.add(username);
        }
        //将拼接好的审批人姓名字符串赋值给申请单VO的AuditUsernameList属性
        auditVO.setAuditUsernameList(sj.toString());
        //将准备好的审批人id集合赋值给申请单VO的AuditUserIdList属性
        auditVO.setAuditUserIdList(auditUserIdList);
    }
}



























